module sw.global.globalmodelist;
import nazo.date, nazo.http, std.uri, std.stdio, nazo.xhtml, nazo.env, nazo.file;
import sw.mode, sw.contentmode, sw.cgiinfo, sw.siteconfig, sw.unsupportedmode, sw.locale.locale, sw.client, sw.modelist, sw.menuitem, sw.main;

/**
 * Globalモード
 */
class GlobalModeFactory:ModeFactory{
  mixin TModeFactory!();
  const static string prefix="global";
  IMode getMode(string name){
    switch(name){
      case "info":
        return new InfoMode(cfg);
      case "foaf":
        return new FoafMode(cfg);
      case "sitemapindex":
        return new SiteMapIndexMode(cfg);
      default:
    }
    return new UnsupportedMode(cfg);
  }
}

///cgiの情報
class InfoMode:XhtmlMode!(){
  this(SiteConfig* cfg){
    super(cfg);
    info=new CgiInfo();
  }
  override d_time lastModified(){
    return info.datetime;
  }
  override string title(){
    return CGI.locale.getValue!(Locale.Page.info)();
  }
  CgiInfo info;
  private void add(Locale.Page id)(inout string content,string val){
    content~="<dt>"~CGI.locale.getValue!(id)()~"</dt>\n<dd>"~(val!=""?val:CGI.locale.getValue!(Locale.Page.infoNone)())~"</dd>\n";
  }
  private void add2(inout string content,string label,string val){
    content~="<dt>"~label~"</dt>\n<dd>"~(val!=""?val:CGI.locale.getValue!(Locale.Page.infoNone)())~"</dd>\n";
  }
  override string contentBody(){
    string content="<dl>\n";
    add!(Locale.Page.infoName)(content,info.name);
    add2(content, "ホームページ","<a href=\""~info.homepage~"\">"~info.homepage~"</a>");
    add!(Locale.Page.infoCreator)(content,info.creator);
    add!(Locale.Page.infoContributor)(content,info.contributor);
    add!(Locale.Page.infoLicense)(content,info.license);
    add!(Locale.Page.infoDLangSpecificationVersion)(content,info.DLangSpecificationVersion);
    add!(Locale.Page.infoVersion)(content,info.ver);
    add!(Locale.Page.infoDatetime)(content,toUTCString(info.datetime));
    add!(Locale.Page.infoCompiler)(content,info.compiler);
    add!(Locale.Page.infoBuildType)(content,info.buildFlag);
    add!(Locale.Page.infoEnableOptions)(content,info.enableOptions);
    add2(content, "CPUのアーキテクチャ",info.cpuArch);
    add2(content, "CPUのエンディアン",info.cpuEndian);
    content~="</dl>";
    return content;
  }
}

class FoafMode:XmlMode!(){
  SiteConfig* cfg;
  this(SiteConfig* cfg){
    super(cfg);
    this.cfg = cfg;
  }
  override string filename(){
    return "foaf.xml";
  }
  override d_time lastModified(){
    return getLastWriteTime(cfg.fileName);
  }
  override string content(){
    string r = "<rdf:RDF "
               "xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" "
               "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">";
    r ~= "<foaf:Person>";
    r ~= "<foaf:name>" ~ cfg.manager ~ "</foaf:name>";
    if(cfg.mailAddr.length)
      r ~= "<foaf:mbox rdf:resource=\"mailto:" ~ cfg.mailAddr ~ "\"/>";
    r ~= "</foaf:Person>";
    r ~= "</rdf:RDF>";
    return r;
  }
}

version(Wiki){
  import sw.wiki.recentlist;
}
version(Upload){
  import sw.upload.uploadlist;
}

class SiteMapIndexMode:XmlMode!(){
  this(SiteConfig* cfg){
    super(cfg);
    version(Wiki){
      recentList=new RecentList;
    }
    version(Upload){
      uploadList=new UploadList;
    }
  }
  override string filename(){
    return "sitemapindex.xml";
  }
  override d_time lastModified(){
    d_time t = d_time.init;
    version(Wiki){
      if(t < recentList.lastModified)
        t = recentList.lastModified;
    }
    version(Upload){
      if(t < uploadList.lastModified)
        t = uploadList.lastModified;
    }
    return t;
  }
  version(Wiki){
    RecentList recentList;
  }
  version(Upload){
    UploadList uploadList;
  }
  override string content(){
    string r = "<sitemapindex xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
                             "xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\" "
                             "url=\"http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd\" "
                             "xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
    version(Wiki){
      r ~= "<sitemap>";
      r ~= "<loc>" ~ Http.path ~ "?mode=wiki:sitemap</loc>";
      r ~= "<lastmod>" ~ .toISO8610String(recentList.lastModified) ~ "</lastmod>";
      r ~= "</sitemap>";
    }
    version(Upload){
      r ~= "<sitemap>";
      r ~= "<loc>" ~ Http.path ~ "?mode=upload:sitemap</loc>";
      r ~= "<lastmod>" ~ .toISO8610String(uploadList.lastModified) ~ "</lastmod>";
      r ~= "</sitemap>";
    }
    r ~= "</sitemapindex>";
    return r;
  }
}
